/*
 * ResourceWirehouse.cpp
 *
 *  Created on: 18.03.2012
 *      Author: Kirill Blinov
 *      Copyright: LGPL
 */

#include "ResourceWarehouse.h"
#include "UnitFabric.h"

#include "../Dynamic System/CDynamicEngine.h"

CResourceWarehouse::CResourceWarehouse() : vertexArrayId(0), guiDummyObject(NULL)
{

}

CResourceWarehouse::~CResourceWarehouse()
{
	textureDescriptorSet.clear();
	shaderConstructorsSet.clear();
	gameUnitsArray.clear();
	//Destructors for stored units shouldn't be called again
	for ( list<IUnit*>::iterator Begin = gameUnitsList.begin(), End = gameUnitsList.end();
		  Begin != End;
		  Begin++ )
	{
		*Begin = NULL;
	}

	/*for ( boost::unordered_set< string, pair<IUnit*,UINT> >::iterator Begin = gameUnitsSet.begin(),
																	  End = gameUnitsSet.end();
		  Begin != End;
		  Begin++ )
	{
		pair< string, pair<IUnit*,UINT> > TestPair;
		pair<IUnit*,UINT> *ResultPair = TestPair.second;
		ResultPair->first = NULL;
	}*/

	delete guiDummyObject;
}

bool
CResourceWarehouse::AddTextureDescriptor( TEXTURE_DESCRIPTOR* Descriptor )
{
	std::pair<boost::unordered_map< string, TEXTURE_DESCRIPTOR* >::iterator,bool> InsertResult;
	InsertResult = textureDescriptorSet.emplace( Descriptor->name, Descriptor );
	return InsertResult.second;
}

bool
CResourceWarehouse::ReplaceTexureDescriptor( TEXTURE_DESCRIPTOR* Descriptor )
{
	bool Result = false;
	boost::unordered_map< string, TEXTURE_DESCRIPTOR* >::const_iterator End = textureDescriptorSet.end();
	boost::unordered_map< string, TEXTURE_DESCRIPTOR* >::iterator Found =
			                                             textureDescriptorSet.find( Descriptor->name );
	if ( End != Found )
	{
		Result = true;
		RemoveTexureDescriptorByIterator( Found );
		textureDescriptorSet.emplace( Descriptor->name, Descriptor );
	}
	return Result;
}

TEXTURE_DESCRIPTOR*
CResourceWarehouse::GetTextureDescriptorByName( const string DescriptorName )
{
	TEXTURE_DESCRIPTOR* Result = NULL;
	boost::unordered_map< string, TEXTURE_DESCRIPTOR* >::iterator Found =
			                                             textureDescriptorSet.find( DescriptorName );

	if ( textureDescriptorSet.end() != Found )
	{
		Result = Found->second;
	}

	return Result;
}

void
CResourceWarehouse::RemoveTextureDescriptorByName( const string DescriptorName )
{
	boost::unordered_map< string, TEXTURE_DESCRIPTOR* >::iterator Found =
				                                             textureDescriptorSet.find( DescriptorName );
	if ( textureDescriptorSet.end() != Found )
	{
		RemoveTexureDescriptorByIterator( Found );
	}
}

bool
CResourceWarehouse::CreateShaderProgramConstructor( const string Name,
													GLuint ProgramName,
													std::vector<IShaderParamParser*> ParsersArray,
													std::string LoadedShaderParameters,
													std::vector< std::string > SortedShaderTextures )
{
	CShaderConstructor* ShaderConstructor = new CShaderConstructor( Name,
																	ProgramName,
																	ParsersArray,
																	LoadedShaderParameters,
																	SortedShaderTextures );

	std::pair<boost::unordered_map< string, CShaderConstructor* >::iterator,bool> InsertResult;
	InsertResult = shaderConstructorsSet.emplace( Name, ShaderConstructor );
	return InsertResult.second;
}

CShaderConstructor*
CResourceWarehouse::GetShaderProgramConstructor( const string Name ) const
{
	CShaderConstructor* Result = NULL;
	boost::unordered_map< string, CShaderConstructor* >::const_iterator Found = shaderConstructorsSet.find( Name );

	if ( Found != shaderConstructorsSet.end() )
	{
		Result = Found->second;
	}

	return Result;
}

void
CResourceWarehouse::SaveVertexArrayId( const GLuint ArrayID )
{
	vertexArrayId = ArrayID;
}

GLuint
CResourceWarehouse::GetVertexArrayId() const
{
	return vertexArrayId;
}

void
CResourceWarehouse::RemoveTexureDescriptorByIterator( boost::unordered_map< string, TEXTURE_DESCRIPTOR* >::iterator &Iter )
{
	const TEXTURE_DESCRIPTOR Descriptor = *Iter->second;

	//It's more optimal to delete array of textures
	glDeleteTextures( 1, &Descriptor.textureGLid );

	textureDescriptorSet.erase( Iter );
}

void
CResourceWarehouse::SetGuiDummy( GAME_OBJECT* GuiDummyObject )
{
	guiDummyObject = GuiDummyObject;
}

GAME_OBJECT*
CResourceWarehouse::GetGuiDummy() const
{
	return guiDummyObject;
}

